---
title: "create_key"
description: "Create an api key for your users"
---

> @spec create_key(map) :: map()

Creates an API key for your users.

## Request

<ParamField body="apiId" type="string" required>
  Choose an `API` where this key should be created.
</ParamField>

<ParamField body="prefix" type="string" >
To make it easier for your users to understand which product an api key belongs to, you can add prefix them.

For example Stripe famously prefixes their customer ids with `cus_` or their api keys with `sk_live_`.

The underscore is automtically added if you are defining a prefix, for example: `"prefix": "abc"` will result in a key like `abc_xxxxxxxxx`

</ParamField>

<ParamField body="byteLength" type="int" default={16} >
The bytelength used to generate your key determines its entropy as well as its length.
Higher is better, but keys become longer and more annoying to handle.

The default is `16 bytes`, or 2<sup>128</sup> possible combinations

 </ParamField>

 <ParamField body="ownerId" type="string" >
  Your user's Id. This will provide a link between Unkey and your customer record.

When validating a key, we will return this back to you, so you can clearly identify your user from their api key.

</ParamField>

<ParamField body="meta" type="object" >
This is a place for dynamic meta data, anything that feels useful for you should go here

Example:

```json
{
  "billingTier": "PRO",
  "trialEnds": "2023-06-16T17:16:37.161Z"
}
```

</ParamField>
<ParamField body="expires" type="int" >
  You can auto expire keys by providing a unix timestamp in milliseconds.

Once keys expire they will automatically be deleted and are no longer valid.

</ParamField>

<ParamField body="ratelimit" type="Object" >

Unkey comes with per-key ratelimiting out of the box.

  <Expandable title="properties">

  <ParamField body="type" type="string" default="fast" required>
  Either `fast` or `consistent`.

Read more [here](/apis/features/ratelimiting)

  </ParamField>
  <ParamField body="limit" type="int" required>
  The total amount of burstable requests.

  </ParamField>
  <ParamField body="refillRate" type="int" required>
  How many tokens to refill during each `refillInterval`
  </ParamField>
  <ParamField body="refillInterval" type="int" required>
  Determines the speed at which tokens are refilled.

In milliseconds

  </ParamField>
 </Expandable>
</ParamField>

 <ParamField body="remaining" type="int" >
  Optionally limit the number of times a key can be used. This is different from time-based expiration using `expires`.

Example:

```json
"remaining": 10
```

The created key can be verified successfully 10 times, afterwards it is invalidated automatically.

Read more [here](/apis/features/remaining)

</ParamField>

## Response

<ResponseField name="key" type="string" required>
  The newly created api key
</ResponseField>

<ResponseField name="keyId" type="string" required>
  A unique id to reference this key for updating or revoking. This id can not be
  used to verify the key.
</ResponseField>

<RequestExample>

```elixir
   try do
        expiry =
          DateTime.utc_now()
          |> DateTime.add(100_000)
          |> DateTime.to_unix(:millisecond)

        opts =
          UnkeyElixirSdk.create_key(%{
            "apiId" => "api_7oKUUscTZy22jmVf9THxDA",
            "prefix" => "xyz",
            "byteLength" => 16,
            "ownerId" => "glamboyosa",
            "meta" => %{"hello" => "world"},
            "expires" => expiry,
            "ratelimit" => %{
              "type" => "fast",
              "limit" => 10,
              "refillRate" => 1,
              "refillInterval" => 1000
            },
            "remaining" => 10
          })

        Logger.info(opts)
      catch
        err ->
          Logger.error(err)
      end
```

</RequestExample>

<ResponseExample>
```json
{
	"key": "xyz_AS5HDkXXPot2MMoPHD8jnL",
     "keyId": "key_cm9vdCBvZiBnb29kXa",
}
```

</ResponseExample>
